package team.bluepen.order.web.servlet.order;

import team.bluepen.order.data.database.hive.OrderRepository;
import team.bluepen.order.data.entity.Order;
import team.bluepen.order.util.Log;
import team.bluepen.order.util.StringUtil;
import team.bluepen.order.web.servlet.BaseServlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author RollW
 */
@WebServlet(name = "OrderQueryServlet",
        urlPatterns = {"/api/order/query", "/api/order/get"})
public class OrderQueryServlet extends BaseServlet {
    public static final String NAME_PARAM = "name";
    public static final String ID_PARAM = "id";
    public static final String VALID_PARAM = "valid";
    public static final String DATE_PARAM = "date";
    private final OrderRepository repository = new OrderRepository();

    @Override
    protected void post(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String nameParam = req.getParameter(NAME_PARAM);
        String idParam = req.getParameter(ID_PARAM);
        String validParam = req.getParameter(VALID_PARAM);
        String dateParam = req.getParameter(DATE_PARAM);
        setJsonHeader(resp);

        List<Order> orderList = filterByName(nameParam, idParam, validParam, dateParam);
        writeJson(resp, orderList);
    }

    private static boolean allEmpty(String... strings) {
        for (String string : strings) {
            if (!StringUtil.isEmpty(string)) {
                return false;
            }
        }
        return true;
    }


    private List<Order> filterByName(String name, String idParam,
                                     String validParam, String dateParam) {
        if (StringUtil.isEmpty(name)) {
            return filterById(null, idParam, validParam, dateParam);
        }
        List<Order> orderList = repository.getOrderDao().get(name);
        return filterById(orderList, idParam, validParam, dateParam);
    }

    private List<Order> filterById(List<Order> orderList, String idParam,
                                   String validParam, String dateParam) {
        if (StringUtil.isEmpty(idParam)) {
            return filterByValid(
                    orderList,
                    validParam, dateParam
            );
        }
        long id = Long.parseLong(idParam);
        List<Order> result = new ArrayList<>();
        if (orderList == null) {
            return filterByValid(
                    repository.getOrderDao().get(id),
                    validParam, dateParam
            );
        }
        orderList.forEach(order -> {
            if (order.getId() == id) {
                result.add(order);
            }
        });
        return result;
    }

    private List<Order> filterByValid(List<Order> orderList, String validParam, String dateParam) {
        if (StringUtil.isEmpty(validParam)) {
            return filterByDate(
                    orderList,
                    dateParam
            );
        }
        if (orderList == null) {
            return filterByDate(
                    repository.getOrderDao().get(Boolean.parseBoolean(validParam)),
                    dateParam
            );
        }
        List<Order> result = new ArrayList<>();
        boolean valid = Boolean.parseBoolean(validParam);
        orderList.forEach(order -> {
            if (order.isValid() == valid) {
                result.add(order);
            }
        });
        return result;
    }

    private List<Order> filterByDate(List<Order> orderList, String dateParam) {
        if (StringUtil.isEmpty(dateParam) && orderList != null) {
            return orderList;
        }
        if (StringUtil.isEmpty(dateParam) && orderList == null) {
            return repository.getOrderDao().get();
        }
        if (orderList == null) {
            return repository.getOrderDao().getByDate(dateParam);
        }
        List<Order> result = new ArrayList<>();
        orderList.forEach(order -> {
            if (Objects.equals(order.getDate(), dateParam)) {
                result.add(order);
            }
        });
        return result;
    }

}
